/**
 * 
 */
package pruebas.tiendaOl.dominio.servicio;

import iades.fabricaciones.InterceptorTransaccional.TransaccionUnidaAUnidadTrabajo;
import iades.fabricaciones.UnidadTrabajo;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.logging.Logger;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.enterprise.context.ConversationScoped;
import javax.enterprise.context.Dependent;
import javax.enterprise.event.Event;
import javax.enterprise.event.Observes;
import javax.enterprise.event.TransactionPhase;
import javax.enterprise.inject.Any;
import javax.inject.Inject;

import pruebas.tiendaOl.dominio.casosUso.CasosUsoCliente;
import pruebas.tiendaOl.dominio.entidades.Gondola.EventoGondola;
import pruebas.tiendaOl.dominio.entidades.ItemGondola;
import pruebas.tiendaOl.dominio.entidades.TipoArticulo;
import pruebas.tiendaOl.ipsWeb.IpsGondola;

import com.intelap.incrustables.Dinero;

/** Proveedor del servicio: acceso a la gondola.
 * Nota: Se usó {@link ConversationScoped} en lugar de {@link Dependent} (que sería mas apropiado porque no existiria la exigencia de tener el mismo context scope que el cliente para no perder o duplicar observadores), para que sea el observador de eventos de la instancia asociada al cliente el que reciba los eventos en lugar de la instancia que crearía CDI si fuera {@link Dependent}.
 * @author Gustavo */
@Dependent
public class PsGondola implements IpsGondola {
	@Inject
	private CasosUsoCliente casosUsoCliente;
	@Inject
	private UnidadTrabajo ut;

	@Override
	@TransaccionUnidaAUnidadTrabajo
	public List<IpsItemGondola> getItems() {
			List<IpsItemGondola> items;
				Collection<ItemGondola> itemsGenuinos = this.casosUsoCliente.getGondola().getItems_const().values();
				items = new ArrayList<>(itemsGenuinos.size());
				for (ItemGondola item : itemsGenuinos) {
					assert ut.contiene(item);
					items.add(new IpsItemGondolaImpl(item.getTipoArticulo(), item.getCantidad()));
				}
			return items;
	}

	@Override
	public void ponerArticulosEnCarrito(IpsItemGondola itemGondola, int cantidad) {
		casosUsoCliente.ponerArticulosEnCarrito(((IpsItemGondolaImpl) itemGondola).tipoArticulo, cantidad); // usar esta linea cuando el {@link SustentadorUnidadTrabajo} es SessionScoped
//		casosUsoCliente.ponerArticulosEnCarrito(ut.getInstanciaAtada(((IpsItemGondolaImpl) itemGondola).tipoArticulo), cantidad); // usar esta linea cuando el {@link SustentadorUnidadTrabajo} es RequestScoped
	}

	@Inject
	private Event<EventoCambiosGondola> lanzadorEventoCambiosGondola;
	public void cuandoEventoGondola(
			@Observes(during = TransactionPhase.AFTER_SUCCESS) @Any EventoGondola evento) {
		logger.info("PsGondola#" + System.identityHashCode(this) + ": anunciando " + evento);
		this.lanzadorEventoCambiosGondola.fire(new EventoCambiosGondola() {});
	}

	@Override
	public String getId() {
		return Integer.toString(System.identityHashCode(this));
	}

	private static class IpsItemGondolaImpl implements IpsItemGondola {
		TipoArticulo tipoArticulo;
		int cantidad;

		IpsItemGondolaImpl(TipoArticulo tipoArticulo, int cantidad) {
			this.tipoArticulo = tipoArticulo;
			this.cantidad = cantidad;
		}

		@Override
		public String getNombre() {
			return tipoArticulo.getNombre();
		}

		@Override
		public Dinero getPrecio() {
			return tipoArticulo.getPrecio();
		}

		@Override
		public int getCantidad() {
			return cantidad;
		}
	}


	//// Debug ////
	@Inject
	private Logger logger;
	@PostConstruct
	void postConstruct() {
		logger.info("postConstruct de PsGondola#" + System.identityHashCode(this));
	}
	@PreDestroy
	void preDestroy() {
		logger.info("preDestroy de PsGondola#" + System.identityHashCode(this));
	}
}
